/*#include<stdio.h>
#include<stdlib.h>

#define ERROR 0
#define OK 1
typedef int ElemType;

typedef struct DuLNode{
    ElemType data;
    struct DuLNode *prior,*next;
}DuLNode,*DuLinkList;

DuLinkList CreateList_DuL(){
    DuLinkList L=(DuLinkList)malloc(sizeof(DuLNode));
    if(L==NULL)
    {
        return NULL;
    }
    L->prior=L;
    L->next=L;
    return L;
}  

DuLinkList GetElem_DulL(DuLinkList L,int i){
    if(L==NULL||i<1){
        return NULL;
    }
    DuLinkList p=L->next;
    int j=1;
    while(p!=L&&j<i){
        p=p->next;
        j++;
    }
    if(p==L||j>i){
        return NULL;
    }
    return p;
}

int ListInsert_DuL(DuLinkList*L,int i,ElemType e){
    DuLinkList p=GetElem_DulL(*L,i);
    if(p==NULL){
        return ERROR;
    }
    DuLinkList s=(DuLinkList)malloc(sizeof(DuLNode));
    if(s==NULL){
        return ERROR;
    }
    s->data=e;
    s->prior=p->prior;
    s->next=p;
    if(p->prior!=NULL){
        p->prior->next=s;
    }
    p->prior=s;
    return OK;
}

int main()
{
    DuLinkList L=CreateList_DuL();
    ListInsert_DuL(&L,1,10);
    ListInsert_DuL(&L,2,20);
    ListInsert_DuL(&L,3,30);

    DuLinkList p=L->next;
    while(p!=L)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    return 0;
}
*/
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0

typedef int ElemType;

typedef struct DuLNode  
{
    ElemType data;  
    struct DuLNode *prior, *next;  // prior指向前驱节点，next指向后继节点
}DuLNode, *DuLinkList;  // DuLinkList是指向双向链表节点的指针类型

DuLinkList CreateList_DuL()  // 创建一个空的双向循环链表
{
    DuLinkList  L = (DuLinkList)malloc(sizeof(DuLNode));  // 创建头节点
    if(L == NULL)  // 内存分配失败
    {
        return NULL;
    }
    L -> prior = L;  // 头节点的前驱和后继都指向自己
    L -> next = L;   
    return L;  // 返回头节点指针
}

// 创建GetElem_DulL函数，返回第i个节点的指针
DuLinkList GetElem_DulL(DuLinkList L, int i)  // i从1开始
{ 
    if(L == NULL || i < 1)  // 空表或i值不合法
    { 
        return NULL;
    }   
    DuLinkList p = L -> next;  // p指向第一个节点
    int j = 1;  // j记录当前节点位置
    while(p != L && j < i)   // 遍历链表，直到找到第i个节点或遍历完整个链表
    {
        p = p -> next;  // p指向下一个节点
        ++j;  
    }
  
    return p;  // 返回第i个节点的指针，若i大于表长则返回NULL
}


//节点插入
int ListInsert_DuL(DuLinkList *L, int i,ElemType  e)   // 在第i个位置插入元素e
{
    DuLinkList p = GetElem_DulL(*L, i);  // 通过GetElem_DulL函数获取第i个节点的指针
    if(p == NULL)   // 第i个节点不存在，插入位置不合法
    {
        return ERROR;  
    }

    DuLinkList s = (DuLinkList)malloc(sizeof(DuLNode));  // 创建新节点
    if(s == NULL)  
    {
        return ERROR;
    }

    s -> data = e;  // 设置新节点的数据域
    s -> prior = p -> prior;  // s的前驱指向p的前驱
    s -> next = p;  // s的后继指向p

    if(p -> prior != NULL) // 如果p的前驱不为空
    {
        p -> prior -> next = s;  // p的前驱节点的后继指向s
    }
    p -> prior = s;  // p的前驱指向s
    return OK;  

}

int main()
{
    DuLinkList L = CreateList_DuL();  // 创建一个空的双向循环链表
    ListInsert_DuL(&L, 1, 10);  // 在第1个位置插入元素10
    ListInsert_DuL(&L, 2, 20);  // 在第2个位置插入元素20
    ListInsert_DuL(&L, 3, 30);  // 在第3个位置插入元素30
    ListInsert_DuL(&L, 1, 0);   // 在第1个位置插入元素0

    DuLinkList p = L -> next;  // p指向第一个节点
    while(p != L)  // 遍历链表，打印所有节点的数据
    {
        printf("%d ", p -> data);  
        p = p -> next;
    }
    putchar(10);

    return 0;    
}
